home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / games / sakiba / source / main.c < prev    next >
Text File  |  2000-06-23  |  13KB  |  540 lines

  1. /*********************************************
  2.  
  3.     格闘シミュレーション「さきば」
  4.  
  5.                 メイン
  6.  
  7.  *********************************************/
  8.  
  9. #include    <stdio.h>
  10. #include    <stdlib.h>
  11. #include    <sys\iocs.h>
  12. #include    <sys\dos.h>
  13.  
  14. #include    "sakiba.h"
  15. #include    "screen.h"
  16. #include    "chranim.h"
  17. #include    "select.h"
  18. #include    "pad.h"
  19. #include    "sound.h"
  20.  
  21.  
  22. CHR_PARAM    chr_param[2];        /* キャラクタパラメータ */
  23.  
  24. int    turn;                /* ターン */
  25. int    mode;                /* モード */
  26.  
  27. static Bool    watch;            /* 観戦モード */
  28.  
  29.  
  30. /*******************************************
  31.     キャラクタシーケンス設定
  32.     引数     chr = キャラクタ
  33.         seq1 = シーケンス(本体)
  34.         seq2 = シーケンス(サブ)
  35.          num = シーケンス番号
  36.  *******************************************/
  37. static
  38. void    chr_sequence(CHR_PARAM* chr, SEQUENCE* seq1, SEQUENCE* seq2)
  39. {
  40.     set_sequence(&chr->spr[0], seq1->pat ? seq1 : NULL);        /* 本体 */
  41.     set_sequence(&chr->spr[1], seq2->pat ? seq2 : NULL);        /* サブ */
  42. }
  43.  
  44. static
  45. void    chr_sequence2(CHR_PARAM* chr, int num)
  46. {
  47.     chr_sequence(chr, &chr->data->seq[num][0], &chr->data->seq[num][1]);
  48. }
  49.  
  50. /*******************************************
  51.     キャラクタ初期化
  52.     引数     chr = パラメータバッファ
  53.          num = プレイヤー番号
  54.          opr = 操作
  55.         data = キャラクタデータ
  56.  *******************************************/
  57. void    init_chr(CHR_PARAM* chr, int num, int opr, CHR_DATA* data)
  58. {
  59.     ACTION*    p;
  60.     int    i;
  61.  
  62.     chr->num = num;                /* プレイヤー番号 */
  63.     chr->operation = opr;            /* 操作 */
  64.     chr->data = data;            /* データ */
  65.  
  66.     load_chr(chr);                /* キャラクタスプライト読み込み */
  67.  
  68.     chr->hit_point = chr->d_hp = HP_MAX;    /* 体力 */
  69.     for (i = 0, p = chr->action; i < 6; i++, p++) {        /* 行動 */
  70.         switch ( i ) {
  71.           case 0 :            /* 構える前 */
  72.             p->kind  = ACT_SUKI;
  73.             p->count = (num == PLAYER1) ? (rnd(3) + 1) : (rnd(2) + 1);
  74.             break;
  75.           case 1 :            /* 防御 */
  76.             p->kind  = ACT_GUARD;
  77.             p->count = GUARD_CNT;
  78.             break;
  79.           default :            /* 未定 */
  80.             p->kind = -1;
  81.             break;
  82.         }
  83.     }
  84. }
  85.  
  86. /**************************************
  87.     キャラクタアニメを進める
  88.     引数    num = プレイヤー番号
  89.     戻り値    アニメーション終端か
  90.  **************************************/
  91. static
  92. Bool    anim_chr(int num)
  93. {
  94.     anim_spr(&chr_param[num].spr[1]);        /* サブ */
  95.     return    anim_spr(&chr_param[num].spr[0]);    /* 本体 */
  96. }
  97.  
  98.  
  99. /******************************
  100.     キャラクタ登場
  101.     戻り値     TRUE : 続行
  102.         FALSE : 終了
  103.  ******************************/
  104. static
  105. Bool    ready_chr(void)
  106. {
  107.     int    i;
  108.  
  109.     mode = MODE_READY;                /* 登場モード */
  110.     chr_sequence2(&chr_param[PLAYER1], SEQ_READY);    /* 登場シーケンス */
  111.     chr_sequence2(&chr_param[PLAYER2], SEQ_READY);
  112.     for (i = 0; i < 250; i++) {
  113.         anim_chr(PLAYER1);            /* キャラクタアニメーション */
  114.         anim_chr(PLAYER2);
  115.         draw_screen();                /* 画面描画 */
  116.         if ( esc_key ) {            /* ゲーム終了 */
  117.             return    FALSE;
  118.         }
  119.  
  120.         if ( i == 100 ) {            /* 構え */
  121.             chr_sequence2(&chr_param[PLAYER1], SEQ_NORMAL);
  122.             chr_sequence2(&chr_param[PLAYER2], SEQ_NORMAL);
  123.         }
  124.         else if ( i == 130 ) {
  125.             set_message(MES_READY);        /* Ready */
  126.         }
  127.         else if ( i == 200 ) {
  128.             set_message(MES_FIGHT);        /* Fight */
  129.         }
  130.     }
  131.     set_message(-1);                /* メッセージ消去 */
  132.     return    TRUE;
  133. }
  134.  
  135. /************************************
  136.     戦闘終了
  137.     引数    win = 勝利者
  138.     戻り値     TRUE : ゲーム続行
  139.         FALSE : ゲーム終了
  140.  ************************************/
  141. static
  142. Bool    end_battle(int win)
  143. {
  144.     int    i;
  145.  
  146.     set_message((win == PLAYER1) ? MES_1P : MES_2P);    /* Win */
  147.     fadeout_music();                /* BGMフェードアウト */
  148.     for (i = 0; i < 370; i++) {
  149.         anim_chr(PLAYER1);            /* キャラクタアニメーション */
  150.         anim_chr(PLAYER2);
  151.         draw_screen();                /* 画面描画 */
  152.         if ( esc_key ) {            /* ゲーム終了 */
  153.             return    FALSE;
  154.         }
  155.  
  156.         if ( (i < 250) && ((get_push(0) & PAD_A) || (get_push(1) & PAD_A)) ) {
  157.             i = 250;
  158.         }
  159.  
  160.         if ( i == 250 ) {
  161.             _iocs_contrast(0);        /* フェードアウト */
  162.         }
  163.     }
  164.     return    TRUE;
  165. }
  166.  
  167.  
  168. /*****************************
  169.     行動の繰り上げ
  170.     引数     act = 行動
  171.  *****************************/
  172. static
  173. void    move_up(ACTION* act)
  174. {
  175.     int    i;
  176.  
  177.     for (i = 0; i < 6 - 1; i++) {
  178.         *act = *(act + 1);
  179.         act++;
  180.     }
  181.     act->kind = -1;
  182. }
  183.  
  184. /**********************
  185.     COM思考
  186.     戻り値    行動
  187.  **********************/
  188. static
  189. int    com_action(void)
  190. {
  191.     ACTION    *o_act, *d_act;
  192.     int    t;
  193.  
  194.     o_act = chr_param[turn].action;            /* 自分の行動 */
  195.     d_act = chr_param[turn ^ 0x01].action;        /* 相手の行動 */
  196.  
  197.     if ( o_act[0].kind == ACT_GUARD ) {
  198.         t = o_act[0].count - d_act[0].count;
  199.         if ( (d_act[0].kind == ACT_ATTACK1) || (d_act[0].kind == ACT_ATTACK2) ) {
  200.             if ( o_act[0].count < d_act[0].count ) {
  201.                 return    ACT_GUARD;
  202.             }
  203.             t -= d_act[1].count;
  204.         }
  205.     }
  206.     else {
  207.         if ( o_act[0].count < d_act[0].count ) {
  208.             if ( d_act[0].kind == ACT_GUARD ) {
  209.                 t = o_act[0].count + o_act[1].count - d_act[0].count;
  210.             }
  211.             else {
  212.                 t = o_act[1].count - DAMAGE_CNT;
  213.             }
  214.         }
  215.         else if ( (d_act[0].kind == ACT_ATTACK1) || (d_act[0].kind == ACT_ATTACK2) ) {
  216.             t = DAMAGE_CNT - d_act[1].count;
  217.         }
  218.         else {
  219.             t = o_act[0].count + o_act[1].count - d_act[0].count;
  220.         }
  221.     }
  222.  
  223.     if ( t > 0 ) {
  224.         if ( rnd(9 + t) > 8 ) {
  225.             return    ACT_ATTACK2;
  226.         }
  227.         if ( rnd(8 + t) > 6 ) {
  228.             return    ACT_ATTACK1;
  229.         }
  230.         return    ACT_GUARD;
  231.     }
  232.     else {
  233.         if ( rnd(7 - t) < 2 ) {
  234.             return    ACT_GUARD;
  235.         }
  236.         if ( rnd(6 - t) > 4 ) {
  237.             return    ACT_ATTACK2;
  238.         }
  239.         return    ACT_ATTACK1;
  240.     }
  241. }
  242.  
  243. /***********************************
  244.     行動入力
  245.     引数    chr = キャラクタ
  246.     戻り値    行動
  247.         -1 : ゲーム終了
  248.  ***********************************/
  249. static
  250. int    input_action(CHR_PARAM* chr)
  251. {
  252.     PAD    pad;
  253.  
  254.     mode = MODE_INPUT;                /* 入力モード */
  255.     while ( 1 ) {
  256.         anim_chr(chr->num ^ 0x01);        /* キャラクタアニメーション */
  257.  
  258.         draw_screen();                /* 画面描画 */
  259.         pad = get_push(chr->num);        /* 入力 */
  260.         if ( esc_key ) {
  261.             return    -1;            /* ゲーム終了 */
  262.         }
  263.         if ( pad & PAD_LEFT ) {
  264.             return    (chr->num == PLAYER1) ? ACT_GUARD : ACT_ATTACK1;
  265.         }
  266.         if ( pad & PAD_RIGHT ) {
  267.             return    (chr->num == PLAYER1) ? ACT_ATTACK1 : ACT_GUARD;
  268.         }
  269.         if ( pad & PAD_UP ) {
  270.             return    ACT_ATTACK2;
  271.         }
  272.     }
  273. }
  274.  
  275. /**********************************
  276.     行動選択
  277.     引数    chr = キャラクタ
  278.     戻り値     TRUE : 続行
  279.         FALSE : 終了
  280.  **********************************/
  281. static
  282. Bool    select_action(CHR_PARAM* chr)
  283. {
  284.     ACTION*    act;
  285.     int    n;
  286.  
  287.     act = chr->action;            /* 行動 */
  288.     while ( act->kind >= 0 ) {        /* 空き検索 */
  289.         act++;
  290.     }
  291.     act->kind = -1;
  292.  
  293.     n = (chr->operation == OPR_PLAYER) ? input_action(chr) : com_action();
  294.                         /* 行動入力 */
  295.     switch ( n ) {
  296.       case ACT_GUARD :            /* 防御 */
  297.         act->kind = ACT_GUARD;
  298.         act->count = GUARD_CNT;
  299.         break;
  300.  
  301.       case ACT_ATTACK1 :            /* 弱攻撃 */
  302.         act->kind = ACT_ATTACK1;
  303.         act->count = chr->data->attack1.before;
  304.         act++;
  305.         act->kind = ACT_SUKI;
  306.         act->count = chr->data->attack1.after;
  307.         break;
  308.  
  309.       case ACT_ATTACK2 :            /* 強攻撃 */
  310.         act->kind = ACT_ATTACK2;
  311.         act->count = chr->data->attack2.before;
  312.         act++;
  313.         act->kind = ACT_SUKI;
  314.         act->count = chr->data->attack2.after;
  315.         break;
  316.  
  317.       default :                /* ゲーム終了 */
  318.         return    FALSE;
  319.     }
  320.     return    TRUE;
  321. }
  322.  
  323. /*******************************************
  324.     行動アニメーション再生
  325.     引数    slow = スローモーションか
  326.  *******************************************/
  327. static
  328. void    play_action(Bool slow)
  329. {
  330.     Bool    loop = TRUE;
  331.  
  332.     while ( loop ) {
  333.         if ( anim_chr(PLAYER1) && (turn == PLAYER1) ) {
  334.             loop = FALSE;
  335.         }
  336.         if ( anim_chr(PLAYER2) && (turn == PLAYER2) ) {
  337.             loop = FALSE;
  338.         }
  339.         draw_screen();                /* 画面描画 */
  340.         if ( slow ) {
  341.             draw_screen();
  342.         }
  343.         if ( esc_key ) {
  344.             return;
  345.         }
  346.     }
  347. }
  348.  
  349.  
  350. /********************************
  351.     攻撃
  352.     引数    atk = 攻撃技
  353.     戻り値    決着がついたか
  354.  ********************************/
  355. static
  356. Bool    attack(ATK_TECH* atk)
  357. {
  358.     CHR_PARAM    *o_chr, *d_chr;
  359.     ACTION        *d_act;
  360.  
  361.     o_chr = &chr_param[turn];            /* 攻撃側 */
  362.     d_chr = &chr_param[turn ^ 0x01];        /* 守備側 */
  363.     d_act = d_chr->action;
  364.  
  365.     chr_sequence(o_chr, &atk->seq1[0], &atk->seq1[1]);    /* 攻撃前シーケンス設定 */
  366.     if ( d_act[0].kind == ACT_GUARD ) {        /* 防御 */
  367.         chr_sequence2(d_chr, SEQ_GUARD);    /* 防御シーケンス設定 */
  368.     }
  369.     play_action(FALSE);                /* アニメーション再生 */
  370.  
  371.     if ( d_act[0].kind == ACT_GUARD ) {        /* 防御 */
  372.         d_chr->hit_point -= atk->power/2;
  373.     }
  374.     else {                        /* ヒット */
  375.         if ( (d_act[0].kind == ACT_ATTACK1) || (d_act[0].kind == ACT_ATTACK2) ) {
  376.             d_act[1].count += d_act[0].count;
  377.             move_up(d_act);
  378.         }
  379.         d_act[0].kind  = ACT_DAMAGE;        /* くらい */
  380.         d_act[0].count = DAMAGE_CNT;
  381.         d_chr->hit_point -= atk->power;
  382.         chr_sequence2(d_chr, SEQ_DAMAGE);    /* くらいシーケンス設定 */
  383.         set_hitmark();                /* ヒットマーク設定 */
  384.     }
  385.     if ( d_chr->hit_point <= 0 ) {
  386.         d_chr->hit_point = 0;
  387.         set_message(MES_KO);            /* K.O. */
  388.     }
  389.  
  390.     slow_bar(FALSE);
  391.     chr_sequence(o_chr, &atk->seq2[0], &atk->seq2[1]);    /* 攻撃後シーケンス設定 */
  392.  
  393.     if ( d_chr->hit_point == 0 ) {            /* 決着 */
  394.         play_action(TRUE);            /* アニメーション再生 */
  395.         chr_sequence2(o_chr, SEQ_WIN);
  396.         chr_sequence2(d_chr, SEQ_LOSE);
  397.         return    TRUE;
  398.     }
  399.     else {
  400.         play_action(FALSE);            /* アニメーション再生 */
  401.         chr_sequence2(o_chr, SEQ_NORMAL);
  402.         chr_sequence2(d_chr, SEQ_NORMAL);
  403.         return    FALSE;
  404.     }
  405. }
  406.  
  407. /********************************
  408.     行動する
  409.     戻り値    決着がついたか
  410.  ********************************/
  411. static
  412. Bool    take_action(void)
  413. {
  414.     CHR_PARAM*    chr;
  415.     ACTION*        act;
  416.     ATK_TECH*    atk;
  417.     Bool        ret = FALSE;
  418.  
  419.     chr = &chr_param[turn];                /* キャラクタ */
  420.     act = chr->action;                /* 行動 */
  421.     atk = NULL;
  422.     if ( act->kind == ACT_ATTACK1 ) {        /* 弱攻撃 */
  423.         atk = &chr->data->attack1;
  424.     }
  425.     else if ( act->kind == ACT_ATTACK2 ) {        /* 強攻撃 */
  426.         atk = &chr->data->attack2;
  427.     }
  428.     if ( --act->count == 0 ) {
  429.         if ( atk == NULL ) {
  430.             draw_screen();
  431.         }
  432.         move_up(act);                /* 繰り上げ */
  433.         if ( atk ) {
  434.             ret = attack(atk);        /* 攻撃 */
  435.         }
  436.         else {
  437.             slow_bar(TRUE);            /* 行動描画 */
  438.             select_action(chr);        /* 行動選択 */
  439.         }
  440.     }
  441.     return    ret;
  442. }
  443.  
  444. /************************************
  445.     ゲームメイン
  446.     引数    chr = キャラクタデータ
  447.         opr = 操作
  448.     戻り値     TRUE : ゲーム続行
  449.         FALSE : 終了
  450.  ************************************/
  451. static
  452. Bool    game_main(CHR_DATA* chr[2], int opr[2])
  453. {
  454.     int    count, win;
  455.  
  456.     for (count = 0; count < 2; count++) {        /* キャラクタ初期化 */
  457.         init_chr(&chr_param[count], count, opr[count], chr[count]);
  458.     }
  459.     play_main_bgm();                /* メインBGM演奏開始 */
  460.     draw_start();                    /* 初期画面描画 */
  461.  
  462.     turn = PLAYER2;                    /* ターン */
  463.     if ( !ready_chr() ) {                /* キャラクタ登場 */
  464.         return    FALSE;
  465.     }
  466.     count = 4;
  467.     win = 0;
  468.     while ( win == 0 ) {
  469.         if ( esc_key ) {
  470.             return    FALSE;            /* ゲーム終了 */
  471.         }
  472.  
  473.         mode = MODE_BATTLE;            /* 戦闘モード */
  474.         anim_chr(PLAYER1);            /* キャラクタアニメーション */
  475.         anim_chr(PLAYER2);
  476.         draw_screen();                /* 画面描画 */
  477.  
  478.         if ( --count == 0 ) {
  479.             turn ^= 0x01;
  480.             if ( take_action() ) {        /* 行動 */
  481.                 break;
  482.             }
  483.             count = 4;
  484.         }
  485.     }
  486.  
  487.     return    end_battle(turn);            /* 戦闘終了 */
  488. }
  489.  
  490. /************
  491.     メイン
  492.  ************/
  493. int    main(int argc, char* argv[])
  494. {
  495.     CHR_DATA*    chr[2];
  496.     int        opr[2];
  497.  
  498.     watch = ((argc >= 2) && ((*argv[1] == 'W') || (*argv[1] == 'w')));
  499.                             /* 観戦モード */
  500.  
  501.     _iocs_tgusemd(0, 2);                /* グラフィック画面使用 */
  502.     _iocs_tgusemd(1, 2);                /* テキスト画面使用 */
  503.     _dos_c_curoff();                /* カーソルOFF */
  504.     _iocs_crtmod(0x0e);                /* 画面モード設定 */
  505.     _iocs_g_clr_on();                /* グラフィック画面表示 */
  506.     _iocs_b_bpoke((void*)0xe82500, 0x12);        /* プライオリティ設定 */
  507.     if ( init_screen() ) {                /* 画面初期化 */
  508.         _iocs_contrast(-2);            /* フェードイン */
  509.         return    1;
  510.     }
  511.     if ( init_sound() ) {                /* 音源初期化 */
  512.         _iocs_contrast(-2);            /* フェードイン */
  513.         return    1;
  514.     }
  515.     srand((unsigned int)_iocs_timeget());        /* 乱数初期化 */
  516.  
  517.     while ( 1 ) {
  518.         if ( watch ) {
  519.             auto_select(chr, opr);        /* 自動選択 */
  520.         }
  521.         else if ( !select(chr, opr) ) {        /* モード・キャラクタ選択 */
  522.             break;
  523.         }
  524.         if ( !game_main(chr, opr) ) {        /* ゲームメイン */
  525.             break;
  526.         }
  527.     }
  528.     stop_music();                    /* 演奏停止 */
  529.  
  530.     _iocs_tgusemd(0, 3);                /* グラフィック画面使用 */
  531.     _iocs_tgusemd(1, 3);                /* テキスト画面使用 */
  532.     _dos_c_width(0);                /* 画面モード設定 */
  533.     _dos_c_curon();                    /* カーソルON */
  534.     _dos_kflushio(0xff);                /* キーバッファクリア */
  535.     _iocs_contrast(-2);                /* フェードイン */
  536.  
  537.     return    0;
  538. }
  539.  
  540. /****************** End of File ***************************************************/